package com.tumblr.logico2012.screens;

import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PImage;

import com.tumblr.logico2012.gestures.GestureManager;
import com.tumblr.logico2012.gestures.IClickGesture;
import com.tumblr.logico2012.gestures.IGesture;
import com.tumblr.logico2012.gestures.ISwipeGesture;

import static com.tumblr.logico2012.AppletLogico.DISABLE_CAMERA;

/**
 * Selection screen. The interface IScreen is not completely implemented: the
 * method leave is implemented in AppletLogico.SelectGameScreen.
 * 
 * The return value of the screen is the selected game.
 */
public abstract class ISelectGameScreen implements IScreen {
	protected PApplet p;

	public static final int HIGHLIGHT = 30;
	
	// SENSIBILITY
	int sensibility = 50;

	// COLORS
	int clBackground;
	int clForeground;

	// FONTS
	PFont fFrontgame;
	PFont fBackgame;
	PFont fBackgameSmall;

	// GAMES
	int game = 0, numGames;

	// CONTEXT
	protected PImage[] m_images;
	protected String[] m_titles;
	protected int m_shake;
	protected int m_moving;
	protected boolean m_highlight;

	public ISelectGameScreen(PApplet processor, GestureManager manager, PImage[] images, String[] titles) {
		p = processor;
		m_images = images;
		m_titles = titles;
		numGames = m_images.length;
		m_shake = 0;
		m_moving = 0;
		m_highlight = false;

		clBackground = p.color(230,220,210);
		clForeground = p.color(30,20,10);
		fFrontgame = p.createFont("Georgia Bold", 30);
		fBackgame = p.createFont("Georgia", 20);
		fBackgameSmall = p.createFont("Georgia", 10);
		
		manager.setGestureInstruction("click", "Select");
		manager.setGestureInstruction("swipeRight", null);
		manager.setGestureInstruction("swipeLeft", "Change game");
	}
	
	@Override
	public void registerUser(GestureManager manager, int userId) {
	    //manager.addGesture(new SwipeRightGesture(userId, IGesture.RIGHT));
	    manager.addGesture(new SwipeRightGesture(userId, IGesture.LEFT));
	    manager.addGesture(new SwipeLeftGesture(userId, IGesture.RIGHT));
	    //manager.addGesture(new SwipeLeftGesture(userId, IGesture.LEFT));	
	    manager.addGesture(new ClickGesture(userId, IGesture.RIGHT));
	    manager.addGesture(new ClickGesture(userId, IGesture.LEFT));
	}
	
	@Override
	public void keyPressed() {
		if(DISABLE_CAMERA) {
			switch(p.key){
			case PApplet.ENTER:
				leave();
				break;
			case PApplet.CODED:
				switch(p.keyCode) {
				case PApplet.LEFT:
					previousGame();
					break;
				case PApplet.RIGHT:
					nextGame();
					break;
				}
				break;
			}
		}
	}
	
	@Override
	public void draw() {
		p.background(clBackground);

		String output = "";
		int clPlay = p.color(clForeground);

		//p.textFont(fHeader); p.text(game + "", 0, 50);

		// --------- front game
		p.fill(clPlay);
		p.textFont(fFrontgame);

		int shaking;
		if(m_shake > 0) {
			if(m_shake%2 == 0) {
				shaking = -20; 
			} else {
				shaking = 20;
			}
			m_shake--;
		} else {
			shaking = 0;
		}
		if(m_moving < 0) {
			m_moving = Math.max(m_moving - 2, -20);
		} else if(m_moving > 0) {
			m_moving = Math.min(m_moving + 2, 20);
		}
		p.stroke(clPlay); p.strokeWeight(5);
		p.rect(p.width/2 - 150 + shaking + m_moving - (m_highlight?HIGHLIGHT/2:0), p.height/2 + 50 - (m_highlight?HIGHLIGHT/2:0), 300+(m_highlight?HIGHLIGHT:0), 200+(m_highlight?HIGHLIGHT:0));
		p.image(m_images[game % numGames], p.width/2 - 150 + shaking + m_moving - (m_highlight?HIGHLIGHT/2:0), p.height/2 + 50 - (m_highlight?HIGHLIGHT/2:0), 300+(m_highlight?HIGHLIGHT:0), 200+(m_highlight?HIGHLIGHT:0));
		output = m_titles[game % numGames];
		p.text(output, p.width/2 - p.textWidth(output)/2 + shaking + m_moving, p.height/2 + 280);

		// --------- background games
		p.fill(clForeground); 
		p.textFont(fBackgame);

		p.stroke(clForeground); p.strokeWeight(4);
		p.rect(p.width/2 - 380, p.height/2 - 20, 180, 120);
		p.rect(p.width/2 + 200, p.height/2 - 20, 180, 120);
		p.image(m_images[(game+1) % numGames], p.width/2 - 380, p.height/2 - 20, 180, 120);
		output = m_titles[(game+1) % numGames];
		p.text(output, p.width/2 - 290 - p.textWidth(output)/2, p.height/2 + 120);
		p.image(m_images[(game+7) % numGames], p.width/2 + 200, p.height/2 - 20, 180, 120);
		output = m_titles[(game+7) % numGames];
		p.text(output, p.width/2 + 290 - p.textWidth(output)/2, p.height/2 + 120);

		p.stroke(clForeground); p.strokeWeight(3);
		p.rect(p.width/2 - 270, p.height/2 - 150, 120, 90);
		p.rect(p.width/2 + 150, p.height/2 - 150, 120, 90);
		p.image(m_images[(game+2) % numGames], p.width/2 - 270, p.height/2 - 150, 120, 90);
		output = m_titles[(game+2) % numGames];
		p.text(output, p.width/2 - 210 - p.textWidth(output)/2, p.height/2 - 40);
		p.image(m_images[(game+6) % numGames], p.width/2 + 150, p.height/2 - 150, 120, 90);
		output = m_titles[(game+6) % numGames];
		p.text(output, p.width/2 + 210 - p.textWidth(output)/2, p.height/2 - 40);

		p.textFont(fBackgameSmall);

		p.stroke(clForeground); p.strokeWeight(2);
		p.rect(p.width/2 - 165, p.height/2 - 240, 90, 60);
		p.rect(p.width/2 + 75, p.height/2 - 240, 90, 60);
		p.image(m_images[(game+3) % numGames], p.width/2 - 165, p.height/2 - 240, 90, 60);
		output = m_titles[(game+3) % numGames];
		p.text(output, p.width/2 - 120 - p.textWidth(output)/2, p.height/2 - 170);
		p.image(m_images[(game+5) % numGames], p.width/2 +  75, p.height/2 - 240, 90, 60);
		output = m_titles[(game+5) % numGames];
		p.text(output, p.width/2 + 120 - p.textWidth(output)/2, p.height/2 - 170);

		p.stroke(clForeground); p.strokeWeight(1);
		p.rect(p.width/2 - 30, p.height/2 - 270, 60, 40);
		p.image(m_images[(game+4) % numGames], p.width/2 - 30, p.height/2 - 270, 60, 40);
		output = m_titles[(game+4) % numGames];
		p.text(output, p.width/2 - p.textWidth(output)/2, p.height/2 - 220);
	}

	@Override
	public String returnValue() {
		return new Integer(game).toString();
	}

	public void shake() {
		m_shake = 6;
	}
	
	public void nextGame() {
		game = (game + 1) % numGames;
	}
	
	public void previousGame() {
		game = (game==0)?7:(game - 1);
	}
	
	// gestures
	class ClickGesture extends IClickGesture {
		public ClickGesture(int userId, int hand) {
			super(userId, hand, ISelectGameScreen.this.p, "click");
		}

		@Override
		public void gestureAborted(GestureManager manager) {
			m_highlight = false;
			PApplet.println("click aborted!");
		}

		@Override
		public void gestureEnded(GestureManager manager) {
			m_highlight = false;
			PApplet.println("click ended!");
			leave(); // we leave the screen: a game has been selected
		}

		@Override
		public void gestureStarted(GestureManager manager) {
			m_highlight = true;
			PApplet.println("click started!");
		}
	}
	
	class SwipeRightGesture extends ISwipeGesture {
		public SwipeRightGesture(int userId, int hand) {
			super(userId, hand, IGesture.RIGHT, ISelectGameScreen.this.p, "swipeRight");
		}

		@Override
		public void gestureAborted(GestureManager manager) {
			PApplet.println("swipe right aborted!");
			m_moving = 0;
			shake();
		}

		@Override
		public void gestureEnded(GestureManager manager) {
			m_moving = 0;
			nextGame();
		}

		@Override
		public void gestureStarted(GestureManager manager) {
			m_moving = 1;
		}
	}
	
	class SwipeLeftGesture extends ISwipeGesture {
		public SwipeLeftGesture(int userId, int hand) {
			super(userId, hand, IGesture.LEFT, ISelectGameScreen.this.p, "swipeLeft");
		}

		@Override
		public void gestureAborted(GestureManager manager) {
			PApplet.println("swipe left aborted!");
			m_moving = 0;
			shake();
		}

		@Override
		public void gestureEnded(GestureManager manager) {
			m_moving = 0;
			previousGame();
		}

		@Override
		public void gestureStarted(GestureManager manager) {
			m_moving = -1;
		}
	}	
}
